﻿#include <iostream>
#include <vector>
#include <functional>
#include <numeric>
#include <complex>
#include <valarray>
#include <cmath>

void greet() {
	std::cout << "Hello, World!" << std::endl;
}

int add(int a, int b) {
	return a + b;
}

int main()
{

	//迭代器主要分为以下几类：
	//输入迭代器（Input Iterator）：只能进行单次读取操作，不能进行写入操作。
	//输出迭代器（Output Iterator）：只能进行单次写入操作，不能进行读取操作。
	//正向迭代器（Forward Iterator）：可以进行读取和写入操作，并且可以向前移动。
	//双向迭代器（Bidirectional Iterator）：除了可以进行正向迭代器的所有操作外，还可以向后移动。
	//随机访问迭代器（Random Access Iterator）：除了可以进行双向迭代器的所有操作外，还可以进行随机访问，例如通过下标访问元素。

	 // 创建一个 vector 容器并初始化
	std::vector<int> vec = { 1, 2, 3, 4, 5 };

	// 使用迭代器遍历 vector
	for (std::vector<int>::iterator it = vec.begin(); it != vec.end(); ++it) {
		std::cout << *it << " ";
	}
	std::cout << std::endl;

	// 使用 auto 关键字简化迭代器类型
	for (auto it = vec.begin(); it != vec.end(); ++it) {
		std::cout << *it << " ";
	}
	std::cout << std::endl;

	// 使用 C++11 范围 for 循环
	for (int elem : vec) {
		std::cout << elem << " ";
	}
	std::cout << std::endl;




	//<functional> 头文件提供了一组函数模板，这些模板允许我们使用函数对象
	// （function objects）作为参数传递给算法，或者作为算法的返回值
	std::function<void()> f = greet; // 使用函数
	f(); // 输出: Hello, World!

	std::function<void()> lambda = []() {
		std::cout << "Hello, Lambda!" << std::endl;
		};
	lambda(); // 输出: Hello, Lambda!


	//std::bind 允许我们创建一个可调用对象，
	// 它在调用时会将给定的参数绑定到一个函数或函数对象。
	auto bound_add = std::bind(add, 5, 33);
	std::cout << bound_add() << std::endl; // 输出: 15

	//accumulate 函数用于计算容器中所有元素的总和
	int sum = std::accumulate(vec.begin(), vec.end(), 0);
	std::cout << "Sum: " << sum << std::endl; // 输出: Sum: 15



	//inner_product 函数用于计算两个容器中对应元素乘积的总和。
	std::vector<int> v1 = { 1, 2, 3 };
	std::vector<int> v2 = { 4, 5, 6 };
	int product_sum = std::inner_product(v1.begin(), v1.end(), v2.begin(), 0);
	std::cout << "Product Sum: " << product_sum << std::endl; // 输出: Product Sum: 32


	//partial_sum 函数用于计算容器中元素的部分和，并将结果存储在另一个容器中。
	std::vector<int> result(v1.size());
	std::partial_sum(v1.begin(), v1.end(), result.begin());
	for (int i : result)
	{
		std::cout << i << " "; // 输出: 1 3 6 
	}
	std::cout << std::endl;

	//adjacent_difference 函数用于计算容器中相邻元素的差值，并将结果存储在另一个容器中。
	std::adjacent_difference(v1.begin(), v1.end(), result.begin());
	for (int i : result) {
		std::cout << i << " "; // 输出: 1 1 1
	}
	std::cout << std::endl;

	//使用 std::gcd 计算两个整数的最大公约数
	int a = 48;
	int b = 18;
	int GCD = std::gcd(a, b);  // 计算 48 和 18 的最大公约数
	std::cout << "GCD: " << GCD << std::endl;  // 输出 6


	//使用 std::lcm 计算两个整数的最小公倍数：
	int LCM = std::lcm(a, b);  // 计算 48 和 18 的最小公倍数
	std::cout << "LCM: " << LCM << std::endl;  // 输出 144




	//使用 std::iota 填充范围内的序列值
	std::vector<int> v(5); // 创建一个包含5个元素的向量
	// 使用 std::iota 填充向量，起始值为1
	std::iota(std::begin(v), std::end(v), 1);
	// 输出填充后的向量
	for (int i : v) {
		std::cout << i << " ";
	}
	std::cout << std::endl; // 输出: 1 2 3 4 5



	//min_element 和 max_element 函数用于找到容器中的最大值和最小值。
	 // 计算最小值和最大值
	int min_val = *std::min_element(v.begin(), v.end());
	int max_val = *std::max_element(v.begin(), v.end());
	// 计算总和
	int sum_val = std::accumulate(v.begin(), v.end(), 0);
	// 计算平均值
	double avg_val = static_cast<double>(sum_val) / v.size();
	// 输出结果
	std::cout << "Min: " << min_val << std::endl;
	std::cout << "Max: " << max_val << std::endl;
	std::cout << "Sum: " << sum_val << std::endl;
	std::cout << "Average: " << avg_val << std::endl;



	/*
	<complex>  : 用于处理复数（complex number），比如信号处理、傅里叶变换、电路分析等。
	一个复数由实部（real part）和虚部（imaginary part）构成，形式：
	z = a + bi
	复数是实数和虚数的组合，通常表示为 a + bi，其中 a 是实部，b 是虚部，i 是虚数单位，满足 i ^ 2 = -1。
	在 C++ 中，复数类型由 std::complex<T> 表示，其中 T 可以是任意的算术类型，如 float、double 或 long double。
	*/
	std::complex<double> z1(3.0, 4.0); // 3 + 4i
	std::complex<double> z2(1.0, -2.0); // 1 - 2i

	std::cout << "z1 = " << z1 << std::endl;
	std::cout << "z2 = " << z2 << std::endl;

	double realPart = z1.real(); // 获取实部
	double imagPart = z1.imag(); // 获取虚部
	std::cout << "z1.real = " << realPart << "," << "z1.imag = " << imagPart << std::endl;

	//四则运算
	auto z3 = z1 + z2;   // (4, 2)
	auto z4 = z1 - z2;   // (2, 6)
	auto z5 = z1 * z2;   // (11, -2)
	auto z6 = z1 / z2;   // (-1, 2)

	std::cout << "z1 + z2 = " << z3 << std::endl;
	std::cout << "z1 * z2 = " << z5 << std::endl;


	std::cout << "模长 |z1| = " << std::abs(z1) << std::endl;     // 5
	std::cout << "幅角 arg(z1) = " << std::arg(z1) << std::endl;  // 0.927 (弧度)
	std::cout << "共轭 conjugate(z1) = " << std::conj(z1) << std::endl; // (3,-4)
	std::cout << "exp(z1) = " << std::exp(z1) << std::endl;       // e^(3+4i)
	std::cout << "sin(z1) = " << std::sin(z1) << std::endl;
	std::cout << "cos(z1) = " << std::cos(z1) << std::endl;



	// 从极坐标生成复数
	double r = 5.0;           // 模长
	double theta = 45;  // 45 度
	std::complex<double> z = std::polar(r, theta);

	std::cout << "极坐标复数 z = " << z << std::endl;  // (3.53553,3.53553)





	//<valarray> 库中的 valarray 类模板允许程序员对数组进行元素级的数学运算，
	//包括加法、减法、乘法、除法等。此外，它还支持更高级的数学函数，如指数、对数、正弦、余弦等。
	std::valarray<double> va1(5); // 创建一个包含10个double元素的valarray
	va1 = 1; // 将所有元素初始化为1
	for (auto i : va1) {
		std::cout << i << " ";
	}
	std::cout << std::endl;

	std::valarray<double> va2(5); // 创建一个包含5个double元素的valarray
	va2 = { 1.0, 2.0, 3.0, 4.0, 5.0 }; // 初始化valarray
	for (auto i : va2) {
		std::cout << i << " ";
	}
	std::cout << std::endl;


	std::valarray<double> Sum = va1 + va2; // 加法
	std::valarray<double> diff = va1 - va2; // 减法
	std::valarray<double> prod = va1 * va2; // 乘法
	std::valarray<double> quot = va1 / va2; // 除法

	std::cout << "Sum: ";
	for (auto i : Sum) {
		std::cout << i << " ";
	}
	std::cout << std::endl;

	std::cout << "Difference: ";
	for (auto i : diff) {
		std::cout << i << " ";
	}
	std::cout << std::endl;

	std::cout << "Product: ";
	for (auto i : prod) {
		std::cout << i << " ";
	}
	std::cout << std::endl;

	std::cout << "Quotient: ";
	for (auto i : quot) {
		std::cout << i << " ";
	}
	std::cout << std::endl;





	std::valarray<double> squares = va2 * va2; // 平方
	std::valarray<double> roots = std::sqrt(va2); // 开方

	std::cout << "Squares: ";
	for (auto i : squares) {
		std::cout << i << " ";
	}
	std::cout << std::endl;

	std::cout << "Square Roots: ";
	for (auto i : roots) {
		std::cout << i << " ";
	}
	std::cout << std::endl;




	//<cmath> 是 C++ 标准库中的一个头文件，它定义了一组数学函数，
	//这些函数可以执行基本的数学运算，如幂运算、三角函数、对数、绝对值等。

	 // 基本数学运算
	std::cout << "abs(-5) = " << abs(-5) << std::endl;
	std::cout << "fmod(5.3, 2) = " << fmod(5.3, 2) << std::endl;

	// 指数和对数函数
	std::cout << "exp(1) = " << exp(1) << std::endl;
	std::cout << "log(2.71828) = " << log(2.71828) << std::endl;
	std::cout << "pow(2, 3) = " << pow(2, 3) << std::endl;

	// 三角函数
	std::cout << "sin(3.14159 / 2) = " << sin(3.14159 / 2) << std::endl;
	std::cout << "cos(3.14159) = " << cos(3.14159) << std::endl;

	// 取整函数
	std::cout << "ceil(2.3) = " << ceil(2.3) << std::endl;
	std::cout << "floor(2.3) = " << floor(2.3) << std::endl;

	// 浮点数检查
	if (isinf(1.0 / 2.0)) {
		std::cout << "x is infinite" << std::endl;
	}




}
